﻿#include "tolua.h"

#include <opencv2/features2d.hpp>
#include <opencv2/xfeatures2d.hpp>

#ifdef __WITH_LUA__

#if __ENABLE_SOL__
sol::state luaState;

namespace sol {
        template <typename T>
        struct unique_usertype_traits<cv::Ptr<T>> {
                typedef T type;
                typedef cv::Ptr<T> actual_type;
                static const bool value = true;

                static bool is_null(const actual_type& ptr) {
                        return ptr == nullptr;
                }

                static type* get (const actual_type& ptr) {
                        return ptr.get();
                }
        };
}

#else
kaguya::State luaState;
#endif
#endif

bool InitThisLua()
{
#ifdef __WITH_LUA__
#if __ENABLE_SOL__
    // open some common libraries
    luaState.open_libraries(sol::lib::base, sol::lib::package);
    //lua.script("print('bark bark bark!')");
#endif
#endif
    return true;
}

cv::Ptr<cv::BRISK> BRISK_create1()
{
    return cv::BRISK::create();
}


bool initFun_Lua()
{
#ifdef __WITH_LUA__

#if __ENABLE_SOL__
//    lua.new_usertype<cv::BRISK>("BRISK",
//        "Create", sol::factories(cv::BRISK::create)
//      );

//    lua.new_usertype<cv::BRISK>("BRISK",
//        sol::constructors<cv::Ptr<cv::BRISK>(sol::this_state)>(),
//        "Create", &cv::BRISK::create
//    );

    //lua.set_function("BRISK_create", sol::resolve<cv::Ptr<cv::BRISK>(int, int, float)> (&cv::BRISK::create) ); // way 3
    //lua["BRISK_create"] = BRISK_create1; // way 1
    //lua["BRISK_create1"] = BRISK_create3;
    //lua.set("BRISK_create", cv::BRISK::create); // way 2
    //lua.set_function("BRISK_create", cv::BRISK::create); // way 3
    //chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::BRISK>(*)(int thresh, int octaves, float patternScale) >(&cv::BRISK::create)),"BRISK_create");

    luaState["BRISK_create"] = static_cast< cv::Ptr<cv::BRISK>(*)(int thresh, int octaves, float patternScale) >(&cv::BRISK::create);

    luaState["ORB_create"] = &cv::ORB::create;

    luaState["MSER_create"] = &cv::MSER::create;

    luaState["FAST_create"] = &cv::FastFeatureDetector::create;

//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::FastFeatureDetector>(*)(int threshold, bool nonmaxSuppression,
//                                                                FastFeatureDetector::DetectorType type) >(&cv::FastFeatureDetector::create)),"FAST_create");

    luaState["AGAST_create"] = &cv::AgastFeatureDetector::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::AgastFeatureDetector>(*)(int threshold,
//                                                                                bool nonmaxSuppression,
//                                                                                AgastFeatureDetector::DetectorType type ) >(&cv::AgastFeatureDetector::create)),"AGAST_create");

    luaState["GFTT_create"] = static_cast< cv::Ptr<cv::GFTTDetector>(*) ( int maxCorners, double qualityLevel, double minDistance,
                                                     int blockSize, bool useHarrisDetector, double k )>(&cv::GFTTDetector::create);
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::GFTTDetector>(*)(int maxCorners, double qualityLevel, double minDistance,
//                                                                        int blockSize, bool useHarrisDetector, double k) >(&cv::GFTTDetector::create)),"GFTT_create");

    luaState["SimpleBlob_create"] = &cv::SimpleBlobDetector::create;
//    //chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::SimpleBlobDetector>(*)(SimpleBlobDetector::Params &parameters) >(&cv::SimpleBlobDetector::create)),"SimpleBlob_create");

    luaState["KAZE_create"] = &cv::KAZE::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::KAZE>(*)(bool extended, bool upright,
//                                                                float threshold,
//                                                                int nOctaves, int nOctaveLayers,
//                                                                KAZE::DiffusivityType diffusivity) >(&cv::KAZE::create)),"KAZE_create");

    luaState["AKAZE_create"] = &cv::AKAZE::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::AKAZE>(*)(AKAZE::DescriptorType descriptor_type,
//                                                                 int descriptor_size, int descriptor_channels,
//                                                                 float threshold, int nOctaves,
//                                                                 int nOctaveLayers, KAZE::DiffusivityType diffusivity) >(&cv::AKAZE::create)),"AKAZE_create");

    luaState["SIFT_create"] = &cv::xfeatures2d::SIFT::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::SIFT>(*)(int nfeatures, int nOctaveLayers,
//                                                                             double contrastThreshold, double edgeThreshold,
//                                                                             double sigma) >(&cv::xfeatures2d::SIFT::create)),"SIFT_create");

    luaState["SURF_create"] = &cv::xfeatures2d::SURF::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::SURF>(*)(double hessianThreshold,
//                                                                             int nOctaves, int nOctaveLayers,
//                                                                             bool extended, bool upright)>(&cv::xfeatures2d::SURF::create)),"SURF_create");

    luaState["FREAK_create"] = &cv::xfeatures2d::FREAK::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::FREAK>(*)(bool orientationNormalized,
//                                                                              bool scaleNormalized,
//                                                                              float patternScale,
//                                                                              int nOctaves,
//                                                                              const std::vector<int>& selectedPairs)>(&cv::xfeatures2d::FREAK::create)),"FREAK_create");

    luaState["StarDetector_create"] = &cv::xfeatures2d::StarDetector::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::StarDetector>(*)(int maxSize, int responseThreshold,
//                                                                                      int lineThresholdProjected,
//                                                                                      int lineThresholdBinarized,
//                                                                                      int suppressNonmaxSize)>(&cv::xfeatures2d::StarDetector::create)),"StarDetector_create");

    luaState["Brief_create"] = &cv::xfeatures2d::BriefDescriptorExtractor::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::BriefDescriptorExtractor>(*)(int bytes,
//                                                                                                 bool use_orientation)>(&cv::xfeatures2d::BriefDescriptorExtractor::create)),"Brief_create");

    luaState["LUCID_create"] = &cv::xfeatures2d::LUCID::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::LUCID>(*)(const int lucid_kernel, const int blur_kernel)>(&cv::xfeatures2d::LUCID::create)),"LUCID_create");

    luaState["LATCH_create"] = &cv::xfeatures2d::LATCH::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::LATCH>(*)(int bytes, bool rotationInvariance,
//                                                                              int half_ssd_size, double sigma)>(&cv::xfeatures2d::LATCH::create)),"LATCH_create");

    luaState["DAISY_create"] = &cv::xfeatures2d::DAISY::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::DAISY>(*)(float radius, int q_radius, int q_theta,
//                                                                              int q_hist, xfeatures2d::DAISY::NormalizationType norm, InputArray H,
//                                                                              bool interpolation, bool use_orientation)>(&cv::xfeatures2d::DAISY::create)),"DAISY_create");

    luaState["MSDDetector_create"] = &cv::xfeatures2d::MSDDetector::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::MSDDetector>(*)(int m_patch_radius, int m_search_area_radius,
//                                                                                    int m_nms_radius, int m_nms_scale_radius, float m_th_saliency, int m_kNN,
//                                                                                    float m_scale_factor, int m_n_scales,
//                                                                                    bool m_compute_orientation)>(&cv::xfeatures2d::MSDDetector::create)),"MSDDetector_create");

    luaState["VGG_create"] = &cv::xfeatures2d::VGG::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::VGG>(*)(int desc, float isigma,
//                                                                            bool img_normalize, bool use_scale_orientation,
//                                                                            float scale_factor, bool dsc_normalize)>(&cv::xfeatures2d::VGG::create)),"VGG_create");

    luaState["BoostDesc_create"] = &cv::xfeatures2d::BoostDesc::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::BoostDesc>(*)(int desc,
//                                                                                  bool use_scale_orientation,
//                                                                                  float scale_factor)>(&cv::xfeatures2d::BoostDesc::create)),"BoostDesc_create");

////    }
//////            else if (typeString == "PCT") {
//////               Ptr<xfeatures2d::PCTSignatures> PctDetector  = cv::xfeatures2d::PCTSignatures::create();
//////               PctDetector->detect(ProcImageMap["InImage"], mKeypoints);
//////            }
//////            else if (typeString == "PCTSQFD") {
//////                Ptr<xfeatures2d::PCTSignaturesSQFD> PctDetector  = cv::xfeatures2d::PCTSignaturesSQFD::create();
//////                PctDetector->detect(ProcImageMap["InImage"], mKeypoints);
//////            }

    luaState["HarrisLaplace_create"] = &cv::xfeatures2d::HarrisLaplaceFeatureDetector::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::HarrisLaplaceFeatureDetector>(*)(int numOctaves,
//                                                                                                     float corn_thresh,
//                                                                                                     float DOG_thresh,
//                                                                                                     int maxCorners,
//                                                                                                     int num_layers)>(&cv::xfeatures2d::HarrisLaplaceFeatureDetector::create)),"HarrisLaplace_create");
//////            else if (typeString == "Affine") {
//////                Ptr<xfeatures2d::AffineFeature2D>
#else
    luaState["BRISK_create"] = static_cast< cv::Ptr<cv::BRISK>(*)(int thresh, int octaves, float patternScale) >(&cv::BRISK::create);

    luaState["ORB_create"] = &cv::ORB::create;

    luaState["MSER_create"] = &cv::MSER::create;

    luaState["FAST_create"] = &cv::FastFeatureDetector::create;

//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::FastFeatureDetector>(*)(int threshold, bool nonmaxSuppression,
//                                                                FastFeatureDetector::DetectorType type) >(&cv::FastFeatureDetector::create)),"FAST_create");

    luaState["AGAST_create"] = &cv::AgastFeatureDetector::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::AgastFeatureDetector>(*)(int threshold,
//                                                                                bool nonmaxSuppression,
//                                                                                AgastFeatureDetector::DetectorType type ) >(&cv::AgastFeatureDetector::create)),"AGAST_create");

    luaState["GFTT_create"] = static_cast< cv::Ptr<cv::GFTTDetector>(*) ( int maxCorners, double qualityLevel, double minDistance,
                                                     int blockSize, bool useHarrisDetector, double k )>(&cv::GFTTDetector::create);
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::GFTTDetector>(*)(int maxCorners, double qualityLevel, double minDistance,
//                                                                        int blockSize, bool useHarrisDetector, double k) >(&cv::GFTTDetector::create)),"GFTT_create");

    luaState["SimpleBlob_create"] = &cv::SimpleBlobDetector::create;
//    //chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::SimpleBlobDetector>(*)(SimpleBlobDetector::Params &parameters) >(&cv::SimpleBlobDetector::create)),"SimpleBlob_create");

    luaState["KAZE_create"] = &cv::KAZE::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::KAZE>(*)(bool extended, bool upright,
//                                                                float threshold,
//                                                                int nOctaves, int nOctaveLayers,
//                                                                KAZE::DiffusivityType diffusivity) >(&cv::KAZE::create)),"KAZE_create");

    luaState["AKAZE_create"] = &cv::AKAZE::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::AKAZE>(*)(AKAZE::DescriptorType descriptor_type,
//                                                                 int descriptor_size, int descriptor_channels,
//                                                                 float threshold, int nOctaves,
//                                                                 int nOctaveLayers, KAZE::DiffusivityType diffusivity) >(&cv::AKAZE::create)),"AKAZE_create");

    luaState["SIFT_create"] = &cv::xfeatures2d::SIFT::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::SIFT>(*)(int nfeatures, int nOctaveLayers,
//                                                                             double contrastThreshold, double edgeThreshold,
//                                                                             double sigma) >(&cv::xfeatures2d::SIFT::create)),"SIFT_create");

    luaState["SURF_create"] = &cv::xfeatures2d::SURF::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::SURF>(*)(double hessianThreshold,
//                                                                             int nOctaves, int nOctaveLayers,
//                                                                             bool extended, bool upright)>(&cv::xfeatures2d::SURF::create)),"SURF_create");

    luaState["FREAK_create"] = &cv::xfeatures2d::FREAK::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::FREAK>(*)(bool orientationNormalized,
//                                                                              bool scaleNormalized,
//                                                                              float patternScale,
//                                                                              int nOctaves,
//                                                                              const std::vector<int>& selectedPairs)>(&cv::xfeatures2d::FREAK::create)),"FREAK_create");

    luaState["StarDetector_create"] = &cv::xfeatures2d::StarDetector::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::StarDetector>(*)(int maxSize, int responseThreshold,
//                                                                                      int lineThresholdProjected,
//                                                                                      int lineThresholdBinarized,
//                                                                                      int suppressNonmaxSize)>(&cv::xfeatures2d::StarDetector::create)),"StarDetector_create");

    luaState["Brief_create"] = &cv::xfeatures2d::BriefDescriptorExtractor::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::BriefDescriptorExtractor>(*)(int bytes,
//                                                                                                 bool use_orientation)>(&cv::xfeatures2d::BriefDescriptorExtractor::create)),"Brief_create");

    luaState["LUCID_create"] = &cv::xfeatures2d::LUCID::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::LUCID>(*)(const int lucid_kernel, const int blur_kernel)>(&cv::xfeatures2d::LUCID::create)),"LUCID_create");

    luaState["LATCH_create"] = &cv::xfeatures2d::LATCH::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::LATCH>(*)(int bytes, bool rotationInvariance,
//                                                                              int half_ssd_size, double sigma)>(&cv::xfeatures2d::LATCH::create)),"LATCH_create");

    luaState["DAISY_create"] = &cv::xfeatures2d::DAISY::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::DAISY>(*)(float radius, int q_radius, int q_theta,
//                                                                              int q_hist, xfeatures2d::DAISY::NormalizationType norm, InputArray H,
//                                                                              bool interpolation, bool use_orientation)>(&cv::xfeatures2d::DAISY::create)),"DAISY_create");

    luaState["MSDDetector_create"] = &cv::xfeatures2d::MSDDetector::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::MSDDetector>(*)(int m_patch_radius, int m_search_area_radius,
//                                                                                    int m_nms_radius, int m_nms_scale_radius, float m_th_saliency, int m_kNN,
//                                                                                    float m_scale_factor, int m_n_scales,
//                                                                                    bool m_compute_orientation)>(&cv::xfeatures2d::MSDDetector::create)),"MSDDetector_create");

    luaState["VGG_create"] = &cv::xfeatures2d::VGG::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::VGG>(*)(int desc, float isigma,
//                                                                            bool img_normalize, bool use_scale_orientation,
//                                                                            float scale_factor, bool dsc_normalize)>(&cv::xfeatures2d::VGG::create)),"VGG_create");

    luaState["BoostDesc_create"] = &cv::xfeatures2d::BoostDesc::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::BoostDesc>(*)(int desc,
//                                                                                  bool use_scale_orientation,
//                                                                                  float scale_factor)>(&cv::xfeatures2d::BoostDesc::create)),"BoostDesc_create");

////    }
//////            else if (typeString == "PCT") {
//////               Ptr<xfeatures2d::PCTSignatures> PctDetector  = cv::xfeatures2d::PCTSignatures::create();
//////               PctDetector->detect(ProcImageMap["InImage"], mKeypoints);
//////            }
//////            else if (typeString == "PCTSQFD") {
//////                Ptr<xfeatures2d::PCTSignaturesSQFD> PctDetector  = cv::xfeatures2d::PCTSignaturesSQFD::create();
//////                PctDetector->detect(ProcImageMap["InImage"], mKeypoints);
//////            }

    luaState["HarrisLaplace_create"] = &cv::xfeatures2d::HarrisLaplaceFeatureDetector::create;
//    chai.add( chaiscript::fun(static_cast< cv::Ptr<cv::xfeatures2d::HarrisLaplaceFeatureDetector>(*)(int numOctaves,
//                                                                                                     float corn_thresh,
//                                                                                                     float DOG_thresh,
//                                                                                                     int maxCorners,
//                                                                                                     int num_layers)>(&cv::xfeatures2d::HarrisLaplaceFeatureDetector::create)),"HarrisLaplace_create");
//////            else if (typeString == "Affine") {
//////                Ptr<xfeatures2d::AffineFeature2D>
#endif
#endif
    return true;
}

cv::Ptr<cv::FeatureDetector> GetDector_Lua( const std::string lines)
{
#ifdef __WITH_LUA__

    //这个只针对特征检测
#if __ENABLE_SOL__
    if(lines.find("BRISK") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::BRISK>>("Ret");
        } catch (...) {
            return cv::BRISK::create();
        }
    }
    else if(lines.find("ORB") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::ORB>>("Ret");
        } catch (...) {
            return cv::ORB::create();
        }
    }
    else if(lines.find("MSER") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::MSER>>("Ret");
        } catch (...) {
            return cv::MSER::create();
        }
    }
    else if(lines.find("FAST") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::FastFeatureDetector>>("Ret");
        } catch (...) {
            return cv::FastFeatureDetector::create();
        }
    }
    else if(lines.find("AGAST") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::AgastFeatureDetector>>("Ret");
        } catch (...) {
            return cv::AgastFeatureDetector::create();
        }
    }
    else if(lines.find("GFTT") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::GFTTDetector>>("Ret");
        } catch (...) {
            return cv::GFTTDetector::create();
        }
    }
    else if(lines.find("SimpleBlob") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::SimpleBlobDetector>>("Ret");
        } catch (...) {
            return cv::SimpleBlobDetector::create();
        }
    }
    else if(lines.find("KAZE") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::KAZE>>("Ret");
        } catch (...) {
            return cv::KAZE::create();
        }
    }
    else if(lines.find("AKAZE") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::AKAZE>>("Ret");
        } catch (...) {
            return cv::AKAZE::create();
        }
    }
    else if(lines.find("SIFT") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::xfeatures2d::SIFT>>("Ret");
        } catch (...) {
            return cv::xfeatures2d::SIFT::create();
        }
    }
    else if(lines.find("SURF") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::xfeatures2d::SURF>>("Ret");
        } catch (...) {
            return cv::xfeatures2d::SURF::create();
        }
    }
    else if(lines.find("FREAK") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::xfeatures2d::FREAK>>("Ret");
        } catch (...) {
            return cv::xfeatures2d::FREAK::create();
        }
    }
    else if(lines.find("StarDetector") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::xfeatures2d::StarDetector>>("Ret");
        } catch (...) {
            return cv::xfeatures2d::StarDetector::create();
        }
    }
    else if(lines.find("Brief") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::xfeatures2d::BriefDescriptorExtractor>>("Ret");
        } catch (...) {
            return cv::xfeatures2d::BriefDescriptorExtractor::create();
        }
    }
    else if(lines.find("LUCID") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::xfeatures2d::LUCID>>("Ret");
        } catch (...) {
            return cv::xfeatures2d::LUCID::create();
        }
    }
    else if(lines.find("LATCH") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::xfeatures2d::LATCH>>("Ret");
        } catch (...) {
            return cv::xfeatures2d::LATCH::create();
        }
    }
    else if(lines.find("DAISY") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::xfeatures2d::DAISY>>("Ret");
        } catch (...) {
            return cv::xfeatures2d::DAISY::create();
        }
    }
    else if(lines.find("MSDDetector") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::xfeatures2d::MSDDetector>>("Ret");
        } catch (...) {
            return cv::xfeatures2d::MSDDetector::create();
        }
    }
    else if(lines.find("VGG") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::xfeatures2d::VGG>>("Ret");
        } catch (...) {
            return cv::xfeatures2d::VGG::create();
        }
    }
    else if(lines.find("BoostDesc") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::xfeatures2d::BoostDesc>>("Ret");
        } catch (...) {
            return cv::xfeatures2d::BoostDesc::create();
        }
    }
//            else if (typeString == "PCT") {
//               Ptr<xfeatures2d::PCTSignatures> PctDetector  = cv::xfeatures2d::PCTSignatures::create();
//               PctDetector->detect(ProcImageMap["InImage"], mKeypoints);
//            }
//            else if (typeString == "PCTSQFD") {
//                Ptr<xfeatures2d::PCTSignaturesSQFD> PctDetector  = cv::xfeatures2d::PCTSignaturesSQFD::create();
//                PctDetector->detect(ProcImageMap["InImage"], mKeypoints);
//            }
    else if(lines.find("HarrisLaplace") != std::string::npos)
    {
        try {
            luaState.script(lines);
            //lua.do_string(lines);
            return luaState.get<cv::Ptr<cv::xfeatures2d::HarrisLaplaceFeatureDetector>>("Ret");
        } catch (...) {
            return cv::xfeatures2d::HarrisLaplaceFeatureDetector::create();
        }
    }
//            else if (typeString == "Affine") {
//                Ptr<xfeatures2d::AffineFeature2D> AffineDetector  = cv::xfeatures2d::AffineFeature2D::create(mKeypoints);
//                AffineDetector->detect(ProcImageMap["InImage"], mKeypoints);
//            }
    else {
        return nullptr;
    }
    //return nullptr;
#else
    if(lines.find("BRISK") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::BRISK::create();
        }
        //return state["BRISK_create"].call<cv::Ptr<cv::BRISK>>(30, 3, 1.0);
        cv::Ptr<cv::FeatureDetector> ret = luaState["Ret"];
        return ret;
    }
    else if(lines.find("ORB") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::ORB::create();
        }
        cv::Ptr<cv::ORB> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::ORB>>(ret);
    }
    else if(lines.find("MSER") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::MSER::create();
        }
        cv::Ptr<cv::MSER> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::MSER>>(ret);
    }
    else if(lines.find("FAST") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::FastFeatureDetector::create();
        }
        cv::Ptr<cv::FastFeatureDetector> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::FastFeatureDetector>>(ret);
    }
    else if(lines.find("AGAST") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::AgastFeatureDetector::create();
        }
        cv::Ptr<cv::AgastFeatureDetector> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::AgastFeatureDetector>>(ret);
    }
    else if(lines.find("GFTT") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::GFTTDetector::create();
        }
        cv::Ptr<cv::GFTTDetector> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::GFTTDetector>>(ret);
    }
    else if(lines.find("SimpleBlob") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::SimpleBlobDetector::create();
        }
        cv::Ptr<cv::SimpleBlobDetector> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::SimpleBlobDetector>>(ret);
    }
    else if(lines.find("KAZE") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::KAZE::create();
        }
        cv::Ptr<cv::KAZE> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::KAZE>>(ret);
    }
    else if(lines.find("AKAZE") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::AKAZE::create();
        }
        cv::Ptr<cv::AKAZE> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::AKAZE>>(ret);
    }
    else if(lines.find("SIFT") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::xfeatures2d::SIFT::create();
        }
        cv::Ptr<cv::xfeatures2d::SIFT> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::xfeatures2d::SIFT>>(ret);
    }
    else if(lines.find("SURF") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::xfeatures2d::SURF::create();
        }
        cv::Ptr<cv::xfeatures2d::SURF> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::xfeatures2d::SURF>>(ret);
    }
    else if(lines.find("FREAK") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::xfeatures2d::FREAK::create();
        }
        cv::Ptr<cv::xfeatures2d::FREAK> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::xfeatures2d::FREAK>>(ret);
    }
    else if(lines.find("StarDetector") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::xfeatures2d::StarDetector::create();
        }
        cv::Ptr<cv::xfeatures2d::StarDetector> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::xfeatures2d::StarDetector>>(ret);
    }
    else if(lines.find("Brief") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::xfeatures2d::BriefDescriptorExtractor::create();
        }
        cv::Ptr<cv::xfeatures2d::BriefDescriptorExtractor> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::xfeatures2d::BriefDescriptorExtractor>>(ret);
    }
    else if(lines.find("LUCID") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::xfeatures2d::LUCID::create();
        }
        cv::Ptr<cv::xfeatures2d::LUCID> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::xfeatures2d::LUCID>>(ret);
    }
    else if(lines.find("LATCH") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::xfeatures2d::LATCH::create();
        }
        cv::Ptr<cv::xfeatures2d::LATCH> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::xfeatures2d::LATCH>>(ret);
    }
    else if(lines.find("DAISY") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::xfeatures2d::DAISY::create();
        }
        cv::Ptr<cv::xfeatures2d::DAISY> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::xfeatures2d::DAISY>>(ret);
    }
    else if(lines.find("MSDDetector") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::xfeatures2d::MSDDetector::create();
        }
        cv::Ptr<cv::xfeatures2d::MSDDetector> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::xfeatures2d::MSDDetector>>(ret);
    }
    else if(lines.find("VGG") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::xfeatures2d::VGG::create();
        }
        cv::Ptr<cv::xfeatures2d::VGG> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::xfeatures2d::VGG>>(ret);
    }
    else if(lines.find("BoostDesc") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::xfeatures2d::BoostDesc::create();
        }
        cv::Ptr<cv::xfeatures2d::BoostDesc> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::xfeatures2d::BoostDesc>>(ret);
    }
//            else if (typeString == "PCT") {
//               Ptr<xfeatures2d::PCTSignatures> PctDetector  = cv::xfeatures2d::PCTSignatures::create();
//               PctDetector->detect(ProcImageMap["InImage"], mKeypoints);
//            }
//            else if (typeString == "PCTSQFD") {
//                Ptr<xfeatures2d::PCTSignaturesSQFD> PctDetector  = cv::xfeatures2d::PCTSignaturesSQFD::create();
//                PctDetector->detect(ProcImageMap["InImage"], mKeypoints);
//            }
    else if(lines.find("HarrisLaplace") != std::string::npos)
    {
        if( !luaState.dostring(lines) )
        {
            return cv::xfeatures2d::HarrisLaplaceFeatureDetector::create();
        }
        cv::Ptr<cv::xfeatures2d::HarrisLaplaceFeatureDetector> ret = luaState["Ret"];
        return ret;
        //return chai.boxed_cast<cv::Ptr<cv::xfeatures2d::HarrisLaplaceFeatureDetector>>(ret);
    }
//            else if (typeString == "Affine") {
//                Ptr<xfeatures2d::AffineFeature2D> AffineDetector  = cv::xfeatures2d::AffineFeature2D::create(mKeypoints);
//                AffineDetector->detect(ProcImageMap["InImage"], mKeypoints);
//            }
    else {
        return nullptr;
    }
#endif

#else
    return cv::xfeatures2d::SIFT::create();
#endif
}
